﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Odyssey.Controls;
using System.Linq;
using System.Collections.Generic;

namespace Odyssey.ViewModels
{

    public interface IIndexedItem
    {
        string Name { get; }
    }

    /// <summary>
    /// DataSource which maintains an ordered collection by name.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class IndexedDataSource<T> : DataSourceBase<T>
        where T : IIndexedItem
    {
        private static readonly string azValues = "#abcdefghijklmnopqrstuvwxyz";
        private static readonly string minValue = "#";

        public IndexedDataSource()
            : base()
        {
            this.Comparer = new IndexedComparer();
        }

        public IndexedDataSource(IEnumerable<T> items, bool isIndexEnabled = true, Func<T, bool> filter = null)
            : base(items, new IndexedComparer(), isIndexEnabled, filter)
        {
        }

        class IndexedComparer : IComparer<T>
        {
            public int Compare(T x, T y)
            {
                return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
            }
        }


        protected override string GetGroupName(T item)
        {
            string key = item.Name;
            return GetKey(key);
        }


        private static string GetKey(string key)
        {
            if (string.IsNullOrEmpty(key) || key.Length == 0) return minValue;

            char c = char.ToLower(key[0]);
            int index = azValues.IndexOf(c);
            if (index < 0) return minValue;
            return c.ToString();
        }

        protected override GroupItem GetGroupItem(T item)
        {
            return base.GetGroupItem(item);
        }

        protected override void Populate(System.Collections.Generic.IEnumerable<T> items, System.Collections.Generic.IComparer<T> comparer)
        {
            if (comparer == null) comparer = Comparer<T>.Default;
            if (CanNotify)
            {
                foreach (var item in items) PrepareItem(item);
            }
            if (IsGroupingEnabled)
            {
                var groups = from item in items
                             group item by GetKey(item.Name) into grp
                             orderby grp.Key
                             select grp;


                foreach (var g in groups)
                {
                    string key = g.Key; // GetKey(g.Key);
                    GroupItem group = new GroupItem(key);
                    Groups.Add(key, group);
                    Items.Add(group);
                    int cnt = 0;
                    foreach (var item in g.OrderBy(x => x, comparer))
                    {
                        cnt++;
                        AddInternal(item);
                    }
                    group.ChildCount = cnt;
                }
            }
            else
            {
                var sorted = items.OrderBy(x => x, comparer);
                foreach (var item in sorted)
                {
                    Items.Add(item);
                }
            }
        }


        protected override bool HasOrderChanged(string propertyName)
        {
            return propertyName == "Name";
        }

        public int IndexOf(object item)
        {
            return Items.IndexOf(item);
        }
    }
}
